import { defineStore } from 'pinia'
import { ref } from 'vue'
import { useRouter } from 'vue-router'

// setup
export const useTagsViewStore = defineStore(
  'tagsView',
  () => {
    // state
    const visitedViews = ref([])
    const cachedViews = ref([])
    const router = useRouter()
    // actions
    function addVisitedView(view) {
      if (visitedViews.value.some((v) => v.path === view.path)) return
      if (view.meta && view.meta.affix) {
        visitedViews.value.unshift(
          Object.assign({}, view, {
            title: view.meta?.title || 'no-name',
          }),
        )
      } else {
        visitedViews.value.push(
          Object.assign({}, view, {
            title: view.meta?.title || 'no-name',
          }),
        )
      }
    }

    function addCachedView(view) {
      const viewName = view.name
      if (cachedViews.value.includes(viewName)) return
      if (!view.meta?.noCache) {
        cachedViews.value.push(viewName)
      }
    }

    function delVisitedView(view) {
      return new Promise((resolve) => {
        for (const [i, v] of visitedViews.value.entries()) {
          if (v.path === view.path) {
            visitedViews.value.splice(i, 1)
            break
          }
        }
        resolve([...visitedViews.value])
      })
    }

    function delCachedView(view) {
      const viewName = view.name
      keepAliveFn(view, false)
      return new Promise((resolve) => {
        const index = cachedViews.value.indexOf(viewName)
        index > -1 && cachedViews.value.splice(index, 1)
        resolve([...cachedViews.value])
      })
    }

    function keepAliveFn(view, flag) {
      if (!view.meta.noCache) {
        const routeList = router.getRoutes()
        for (let i = 0; i < routeList.length; i++) {
          const item = routeList[i]
          if (item.name === view.name) {
            item.meta.keepAlive = flag
            view = item
            break
          }
        }
        router.addRoute('MainPage', view)
        return view
      }
    }

    function delOtherVisitedViews(view) {
      return new Promise((resolve) => {
        visitedViews.value = visitedViews.value.filter((v) => {
          return v.meta?.affix || v.path === view.path
        })
        resolve([...visitedViews.value])
      })
    }

    function delOtherCachedViews(view) {
      const viewName = view.name
      return new Promise((resolve) => {
        const index = cachedViews.value.indexOf(viewName)
        if (index > -1) {
          cachedViews.value = cachedViews.value.slice(index, index + 1)
        } else {
          // if index = -1, there is no cached tags
          cachedViews.value = []
        }
        resolve([...cachedViews.value])
      })
    }

    function updateVisitedView(view) {
      for (let v of visitedViews.value) {
        if (v.path === view.path) {
          v = Object.assign(v, view)
          break
        }
      }
    }

    function addView(view) {
      keepAliveFn(view, true)
      addVisitedView(view)
      addCachedView(view)
    }

    function delView(view) {
      return new Promise((resolve) => {
        delVisitedView(view)
        delCachedView(view)
        resolve({
          visitedViews: [...visitedViews.value],
          cachedViews: [...cachedViews.value],
        })
      })
    }

    function delOtherViews(view) {
      return new Promise((resolve) => {
        delOtherVisitedViews(view)
        delOtherCachedViews(view)
        resolve({
          visitedViews: [...visitedViews.value],
          cachedViews: [...cachedViews.value],
        })
      })
    }

    function delLeftViews(view) {
      return new Promise((resolve) => {
        const currIndex = visitedViews.value.findIndex((v) => v.path === view.path)
        if (currIndex === -1) {
          return
        }
        visitedViews.value = visitedViews.value.filter((item, index) => {
          // affix:true 固定tag，例如“首页”
          if (index >= currIndex || (item.meta && item.meta.affix)) {
            return true
          }

          const cacheIndex = cachedViews.value.indexOf(item.name)
          if (cacheIndex > -1) {
            cachedViews.value.splice(cacheIndex, 1)
          }
          return false
        })
        resolve({
          visitedViews: [...visitedViews.value],
        })
      })
    }
    function delRightViews(view) {
      return new Promise((resolve) => {
        const currIndex = visitedViews.value.findIndex((v) => v.path === view.path)
        if (currIndex === -1) {
          return
        }
        visitedViews.value = visitedViews.value.filter((item, index) => {
          // affix:true 固定tag，例如“首页”
          if (index <= currIndex || (item.meta && item.meta.affix)) {
            return true
          }

          const cacheIndex = cachedViews.value.indexOf(item.name)
          if (cacheIndex > -1) {
            cachedViews.value.splice(cacheIndex, 1)
          }
          return false
        })
        resolve({
          visitedViews: [...visitedViews.value],
        })
      })
    }

    function delAllViews() {
      return new Promise((resolve) => {
        const affixTags = visitedViews.value.filter((tag) => tag.meta?.affix)
        visitedViews.value = affixTags
        cachedViews.value = []
        resolve({
          visitedViews: [...visitedViews.value],
          cachedViews: [...cachedViews.value],
        })
      })
    }

    function delAllVisitedViews() {
      return new Promise((resolve) => {
        const affixTags = visitedViews.value.filter((tag) => tag.meta?.affix)
        visitedViews.value = affixTags
        resolve([...visitedViews.value])
      })
    }

    function delAllCachedViews() {
      return new Promise((resolve) => {
        cachedViews.value = []
        resolve([...cachedViews.value])
      })
    }

    return {
      visitedViews,
      cachedViews,
      addVisitedView,
      addCachedView,
      delVisitedView,
      delCachedView,
      delOtherVisitedViews,
      delOtherCachedViews,
      updateVisitedView,
      addView,
      delView,
      delOtherViews,
      delLeftViews,
      delRightViews,
      delAllViews,
      delAllVisitedViews,
      delAllCachedViews,
    }
  },
  { persist: { storage: sessionStorage } },
)
